home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / ntfs / dos / fnctdsk.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-23  |  13.2 KB  |  538 lines

  1. /*
  2.  
  3.     File: fnctdsk.c
  4.  
  5.     Copyright (C) 1998-2001  Christophe Grenier <grenier@nef.esiea.fr>
  6.   
  7.     This software is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.   
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.   
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22.  
  23.  
  24. #ifdef DJGPP
  25. #include <curses.h>
  26. #else
  27. #include <ncurses.h>
  28. #include <sys/types.h>
  29. #endif
  30. #include <stdio.h>
  31. #include "types.h"
  32. #include "common.h"
  33. #include "fnctdsk.h"
  34. #include "lang.h"
  35. #include "testdisk.h"
  36. #include "hdaccess.h"
  37. extern char* nom_os[256];
  38. extern dword RS_offset;
  39.  
  40. /* BOOT */
  41. dword NT_sect(t_sector_cst B)
  42. { return *((const dword*)&(B[0x28]));
  43. }
  44.  
  45. byte NT_clustersize(t_sector_cst B)
  46. { return B[0x0D];
  47. }
  48.  
  49. int bootable(t_entree_cst E)
  50. {
  51.   return E[0];
  52. }
  53.  
  54. dword sect_rel(t_entree_cst E)
  55. { return *((const dword*)&(E[8]));
  56. }
  57.  
  58. dword nbr_sect(t_entree_cst E)
  59. { return *((const dword*)&(E[12]));
  60. }
  61.  
  62. dword CHS2SR(t_param_disk_cst disk_car,const word C, const byte H, const byte S)
  63. { return ((dword)C*(disk_car->CHS.head+1)+H)*disk_car->CHS.sector+S;
  64. }
  65.  
  66. dword CHS2SR2(t_param_disk_cst disk_car,const t_CHS*CHS)
  67. { return ((dword)CHS->cylinder*(disk_car->CHS.head+1)+CHS->head)*disk_car->CHS.sector+CHS->sector;
  68. }
  69.  
  70. dword CHS2SRext(t_param_disk_cst disk_car,const uint C, const uint H, const uint S)
  71. { return ((dword)C*(disk_car->CHS.head+1)+H)*disk_car->CHS.sector+S;
  72. }
  73.  
  74. dword get_SR(t_param_disk_cst disk_car,t_disk_cst pos)
  75. { return CHS2SR(disk_car,pos->cylinder, pos->head, pos->sector);
  76. }
  77.  
  78. dword get_SR_part(t_param_disk_cst disk_car,t_diskext_cst pos)
  79. { return CHS2SR2(disk_car,&pos->start);
  80. }
  81.  
  82. dword get_SR_param_disk(t_param_disk_cst disk_car)
  83. { return CHS2SR(disk_car,disk_car->CHS.cylinder, disk_car->CHS.head, disk_car->CHS.sector);
  84. }
  85.  
  86. dword get_LBA(t_param_disk_cst disk_car,t_disk_cst pos)
  87. { return get_SR(disk_car,pos)-1;
  88. }
  89.  
  90. dword get_LBA_part(t_param_disk_cst disk_car,t_diskext_cst pos)
  91. { return get_SR_part(disk_car,pos)-1;
  92. }
  93.  
  94. dword get_LBA_param_disk(t_param_disk_cst disk_car)
  95. { return get_SR_param_disk(disk_car)-1;
  96. }
  97.  
  98. t_disk set_pos(t_param_disk_cst disk_car,t_disk pos, dword sect)
  99. {
  100.   pos->sector=(sect%disk_car->CHS.sector)+1;
  101.   sect/=disk_car->CHS.sector;
  102.   pos->head=sect%(disk_car->CHS.head+1);
  103.   pos->cylinder=sect/(disk_car->CHS.head+1);
  104.   return pos;
  105. }
  106.  
  107. void set_pos2(t_param_disk_cst disk_car, t_CHS * CHS, const dword sect)
  108. {
  109.   dword pos=sect-1;
  110.   CHS->sector=(pos%disk_car->CHS.sector)+1;
  111.   pos/=disk_car->CHS.sector;
  112.   CHS->head=pos%(disk_car->CHS.head+1);
  113.   CHS->cylinder=pos/(disk_car->CHS.head+1);
  114. }
  115.  
  116. t_diskext set_posexts(t_param_disk_cst disk_car,t_diskext partition, dword sect)
  117. {
  118.   set_pos2(disk_car,&partition->start,sect);
  119.   return partition;
  120. }
  121.  
  122. t_diskext set_posexte(t_param_disk_cst disk_car,t_diskext partition, dword sect)
  123. {
  124.   set_pos2(disk_car,&partition->end,sect);
  125.   return partition;
  126. }
  127.  
  128. dword get_sect_s(t_param_disk_cst disk_car,t_entree_cst E)
  129. { return CHS2SR(disk_car,s_cyl(E),s_head(E),s_sect(E));
  130. }
  131.  
  132. dword get_sect_e(t_param_disk_cst disk_car,t_entree_cst E)
  133. { return CHS2SR(disk_car,e_cyl(E),e_head(E),e_sect(E));
  134. }
  135.  
  136. t_disk  entree_s2pos(t_param_disk_cst disk_car,t_entree_cst E, t_disk_cst ref, t_disk pos)
  137. {
  138.   return set_pos(disk_car,pos,debut_abs_entree(disk_car,E,ref)); 
  139. }
  140.  
  141. t_disk  entree_e2pos(t_param_disk_cst disk_car,t_entree_cst E, t_disk_cst ref, t_disk pos)
  142. {
  143.   return set_pos(disk_car,pos,fin_abs_entree(disk_car,E,ref));
  144. }
  145.  
  146. void dup_t_CHS(t_CHS * CHS_dest, const t_CHS * CHS_source)
  147. {
  148.   CHS_dest->cylinder=CHS_source->cylinder;
  149.   CHS_dest->head=CHS_source->head;
  150.   CHS_dest->sector=CHS_source->sector;
  151. }
  152.  
  153. int compare2uint(uint a, uint b)
  154. {
  155.   if(a<b)
  156.     return -1;
  157.   else
  158.     if(a==b)
  159.       return 0;
  160.     else
  161.       return 1;
  162. }
  163.  
  164. int compare_CHS(const t_CHS *CHS1, const t_CHS *CHS2)
  165. {
  166.   int res;
  167.   res=compare2uint(CHS1->cylinder,CHS2->cylinder);
  168.   if(res!=0)
  169.     return res;
  170.   res=compare2uint(CHS1->head,CHS2->head);
  171.   if(res!=0)
  172.     return res;
  173.   return compare2uint(CHS1->sector,CHS2->sector);
  174. }
  175.  
  176.  
  177. void dup_t_diskext(t_diskext dest, t_diskext_cst src)
  178. {
  179.   dup_t_CHS(&dest->start,&src->start);
  180.   dup_t_CHS(&dest->end,&src->end);
  181.   dest->disk=src->disk;
  182.   dest->part_type=src->part_type;
  183.   dest->part_size=src->part_size;
  184.   dest->status=src->status;
  185.   dest->order=src->order;
  186.   dest->sect_rel=src->sect_rel;
  187. }
  188.  
  189. void disk_apres(t_param_disk_cst disk_car,t_disk disk_pos)
  190. {
  191.   if (disk_pos->sector<disk_car->CHS.sector)
  192.     disk_pos->sector++;
  193.   else
  194.     if (++disk_pos->head<disk_car->CHS.head)
  195.     {
  196.       disk_pos->sector=1;
  197.     }
  198.     else
  199.       if (++disk_pos->cylinder<disk_car->CHS.cylinder)
  200.       {
  201.     disk_pos->head=0;
  202.     disk_pos->sector=1;
  203.       }
  204. }
  205.  
  206. void disk_avant(t_param_disk_cst disk_car,t_disk disk_pos)
  207. {
  208.   if (disk_pos->sector>1)
  209.     disk_pos->sector--;
  210.   else
  211.     if (disk_pos->head>0)
  212.     {
  213.       disk_pos->head--;
  214.       disk_pos->sector=disk_car->CHS.sector;
  215.     }
  216.     else
  217.       if (disk_pos->cylinder>0)
  218.       {
  219.     disk_pos->cylinder--;
  220.     disk_pos->sector=disk_car->CHS.sector;
  221.     disk_pos->head=disk_car->CHS.head;
  222.       }
  223.       else
  224.       {
  225.     disk_pos->cylinder=0;
  226.     disk_pos->head=0;
  227.     disk_pos->sector=1;
  228.       }
  229. }
  230.  
  231.  
  232. /*Check if no partition is over another*/
  233. int test_over(t_param_disk_cst disk_car,t_entree_cst E1, t_entree_cst E2)
  234. {
  235.   dword s_E1, s_E2;
  236.   s_E1=get_sect_s(disk_car,E1);
  237.   s_E2=get_sect_s(disk_car,E2);
  238.   if(s_E1>s_E2)
  239.     return test_over(disk_car,E2,E1);
  240.   return (get_sect_e(disk_car,E1)>=s_E2);
  241. }
  242.  
  243. dword debut_abs_entree(t_param_disk_cst disk_car,t_entree_cst entree,t_disk_cst ref)
  244. {
  245.   if((os(entree)==P_EXTENDX)||(os(entree)==P_EXTENDED))
  246.     return debut_rel_entree(entree)+RS_offset-1;
  247.   else
  248.     return debut_rel_entree(entree)+get_SR(disk_car,ref)-1;
  249. }
  250.   
  251. dword debut_rel_entree(t_entree_cst entree)
  252. {
  253.   return sect_rel(entree);
  254. }
  255.  
  256. dword fin_rel_entree(t_entree_cst entree)
  257. {
  258.   return sect_rel(entree)+nbr_sect(entree)-1;
  259. }
  260.  
  261. dword fin_abs_entree(t_param_disk_cst disk_car,t_entree_cst entree, t_disk_cst ref)
  262. {
  263.   return fin_rel_entree(entree)+get_LBA(disk_car,ref);
  264. }
  265.  
  266. //void set_entree_CHS(char * entree_CHS,t_CHS *CHS);
  267.  
  268. void partition2entree(t_param_disk_cst disk_car,dword pos,t_diskext_cst partition, t_entree *entree)
  269. {
  270.   if(partition->status==STATUS_PRIM_BOOT)
  271.     (*entree)[0]=0x80;
  272.   else
  273.     (*entree)[0]=0;             /* Non bootable */
  274.   (*entree)[4]=partition->part_type;
  275.   *((dword*)&((*entree)[8]))=get_SR_part(disk_car,partition)-pos;
  276.   if(partition->start.cylinder>1023)
  277.   {
  278.     (*entree)[1]=254;
  279.     (*entree)[2]=63|((1023>>8)<<6);
  280.     (*entree)[3]=(uchar)1023;
  281.   }
  282.   else
  283.   {
  284.     (*entree)[1]=partition->start.head;
  285.     (*entree)[2]=partition->start.sector|((partition->start.cylinder>>8)<<6);
  286.     (*entree)[3]=partition->start.cylinder;
  287.   }
  288.   if(partition->end.cylinder>1023)
  289.   {
  290.     (*entree)[5]=254;
  291.     (*entree)[6]=63|((1023>>8)<<6);
  292.     (*entree)[7]=(uchar)1023;
  293.   }
  294.   else
  295.   {
  296.     (*entree)[5]=partition->end.head;
  297.     (*entree)[6]=partition->end.sector|((partition->end.cylinder>>8)<<6);
  298.     (*entree)[7]=partition->end.cylinder;
  299.   }
  300.   *((dword*)&((*entree)[12]))=partition->part_size;
  301. }
  302.  
  303. int entree2partition(t_param_disk_cst disk_car,dword pos,t_diskext partition, t_entree_cst entree, int status)
  304. {
  305.   dword start_sect, end_sect;
  306.   partition->disk=disk_car->disk;
  307.   partition->part_type=os(entree);
  308.   partition->sect_rel=sect_rel(entree);
  309.   partition->order=0;
  310.   partition->start.cylinder=s_cyl(entree);
  311.   partition->start.head=s_head(entree);
  312.   partition->start.sector=s_sect(entree);
  313.   partition->end.cylinder=e_cyl(entree);
  314.   partition->end.head=e_head(entree);
  315.   partition->end.sector=e_sect(entree);
  316.   partition->part_size=nbr_sect(entree);
  317.  
  318.   switch(status)
  319.   {
  320.     case STATUS_PRIM:
  321.       if(partition->part_type==P_EXTENDX || partition->part_type==P_EXTENDED)
  322.     partition->status=STATUS_EXT;
  323.       else
  324.     if(bootable(entree))
  325.       partition->status=STATUS_PRIM_BOOT;
  326.     else
  327.       partition->status=status;
  328.       break;
  329.     default:
  330.       partition->status=status;
  331.       break;
  332.   }
  333.   switch(partition->part_type)
  334.   {
  335.     case P_EXTENDX:
  336.     case P_EXTENDED:
  337.       start_sect=RS_offset+partition->sect_rel;
  338.       break;
  339.     default:
  340.       start_sect=pos+partition->sect_rel;
  341.       break;
  342.   }
  343. #ifdef SKIP_TEST
  344.   if(partition->start.cylinder<1023)
  345.   {
  346.     if(start_sect!=get_sect_s(disk_car,entree))
  347.     {
  348.       printf("BAD_RS %ld %ld\n",start_sect,get_sect_s(disk_car,entree));
  349.       return BAD_RS;
  350.     }
  351.   }
  352.   else  /* set CHS begin */
  353. #endif
  354.     set_posexts(disk_car,partition,start_sect);
  355.  
  356.   end_sect=start_sect+partition->part_size-1;
  357. #ifdef SKIP_TEST
  358.   if(partition->end.cylinder<1023)
  359.   {
  360.     if(end_sect!=get_sect_e(disk_car,entree))
  361.       return BAD_SCOUNT;
  362.   }
  363.   else  /* set CHS end */
  364. #endif
  365.     set_posexte(disk_car,partition,end_sect);
  366. #ifdef SKIP_TEST
  367.   /* Check CHS */
  368.   if((partition->start.sector==0)||(partition->start.sector>disk_car->CHS.sector))
  369.     return BAD_SS;
  370.   if((partition->end.sector==0)||(partition->end.sector>disk_car->CHS.sector))
  371.     return BAD_ES;
  372.   if(partition->start.head>disk_car->CHS.head)
  373.     return BAD_SH;
  374.   if(partition->start.cylinder>disk_car->CHS.cylinder)
  375.     return BAD_SC;
  376.   if(partition->end.head>disk_car->CHS.head)
  377.       return BAD_EH;
  378.   if(partition->end.cylinder>disk_car->CHS.cylinder)
  379.     return BAD_EC;
  380.   /* Check start < end */
  381.   if(partition->start.cylinder>partition->end.cylinder)
  382.     return BAD_EBS;
  383.   if(partition->start.cylinder==partition->end.cylinder)
  384.   {
  385.     if(partition->start.head>partition->end.head)
  386.       return BAD_EBS;
  387.     if(partition->start.head==partition->end.head)
  388.       if(partition->start.sector>partition->end.sector)
  389.     return BAD_EBS;
  390.   }
  391. #endif
  392.   return 0;
  393. }
  394.  
  395. const char* errmsg_entree2partition(int errcode)
  396. {
  397.   switch(errcode)
  398.   {
  399.     case BAD_SS: return m_BAD_S_SECT;
  400.     case BAD_ES: return m_BAD_E_SECT;
  401.     case BAD_SH: return m_BAD_S_HEAD;
  402.     case BAD_EH: return m_BAD_E_HEAD;
  403.     case BAD_EBS: return m_END_BFR_START;
  404.     case BAD_RS: return m_BAD_RS;
  405.     case BAD_SC: return m_BAD_S_CYL;
  406.     case BAD_EC: return m_BAD_E_CYL;
  407.     case BAD_SCOUNT: return m_BAD_SCOUNT;
  408.   }
  409.   return "";
  410. }
  411.  
  412. int read_MBR(t_param_disk_cst disk_car,void *buffer)
  413. {
  414.   t_disk pos=(t_disk)MALLOC(sizeof(*pos));
  415.   pos->disk=disk_car->disk;
  416.   pos->cylinder=0;
  417.   pos->head=0;
  418.   pos->sector=1;
  419.   if(hd_read(disk_car,1, buffer, pos))
  420.   {
  421.     printf(m_PART_RD_ERR);
  422.     FREE(pos);
  423.     return 1;
  424.   }
  425.   FREE(pos);
  426.   return 0;
  427. }
  428.  
  429. int read_ext(t_param_disk_cst disk_car,void *buffer, const t_diskext partition )
  430. {
  431.   if(hd_read2(disk_car,1, buffer, partition))
  432.   {
  433.     printf(m_PART_RD_ERR);
  434.     return 1;
  435.   }
  436.   return 0;
  437. }
  438.  
  439. int write_MBR(t_param_disk_cst disk_car,void *buffer)
  440. {
  441.   t_disk pos=(t_disk)MALLOC(sizeof(*pos));
  442.   pos->disk=disk_car->disk;
  443.   pos->cylinder=0;
  444.   pos->head=0;
  445.   pos->sector=1;
  446.   if(hd_write(disk_car,1, buffer, pos))
  447.   {
  448.     printf(m_PART_WR_ERR);
  449.     FREE(pos);
  450.     return 1;
  451.   }
  452.   FREE(pos);
  453.   return 0;
  454. }
  455.  
  456. int write_ext(t_param_disk_cst disk_car,void *buffer, const t_diskext partition )
  457. {
  458.   if(hd_write2(disk_car,1, buffer, partition))
  459.   {
  460.     printf(m_PART_WR_ERR);
  461.     return 1;
  462.   }
  463.   return 0;
  464. }
  465.  
  466. t_list_part add_new_partition(t_list_part old, t_list_part new)
  467. {
  468.   if(new==NULL)
  469.     return old;
  470.   new->prev=NULL;
  471.   new->next=old;
  472.   if(old)
  473.     old->prev=new;
  474.   return new;
  475. }
  476.  
  477. t_list_part insert_new_partition(t_list_part list_part, t_list_part new)
  478. {
  479.   t_list_part prev,next;
  480.   if(!new)
  481.     return list_part;
  482.   if(!list_part || (compar_diskext(list_part->part,new->part)>0))
  483.   {
  484.     new->prev=NULL;
  485.     new->next=list_part;
  486.     if(list_part)
  487.       list_part->prev=new;
  488.     return new;
  489.   }
  490.   for(prev=list_part;;prev=next)
  491.   {
  492.     next=prev->next;
  493.     if(!next || (compar_diskext(next->part,new->part)>0))
  494.     { /* prev new next */
  495.       prev->next=new;
  496.       new->prev=prev;
  497.       new->next=next;
  498.       if(next)
  499.     next->prev=new;
  500.       return list_part;
  501.     }
  502.   }
  503. }
  504.  
  505. int check_list_part(t_list_part list_part)
  506. {
  507.   t_list_part prev=NULL,parts;
  508.   printf("\ncheck_list_part\n");
  509.   for(parts=list_part;parts;parts=parts->next)
  510.   {
  511.     printf("%p %p %p\n",parts->prev, parts, parts->next);
  512.     if(prev!=parts->prev)
  513.     {
  514.       printf("error\n");
  515.       return 1;
  516.     }
  517.     prev=parts;
  518.   }
  519.   return 0;
  520. }
  521.  
  522. t_list_part sort_list_part(t_list_part list_part)
  523. {
  524.   t_list_part new_list_part=NULL,parts,next;
  525.   for(parts=list_part;parts;parts=next)
  526.   {
  527.     next=parts->next;
  528.     new_list_part=insert_new_partition(new_list_part,parts);
  529.   }
  530.   return new_list_part;
  531. }
  532.  
  533. int compar_diskext(const t_diskext a, const t_diskext b)
  534. {
  535.   return compare_CHS(&a->start,&b->start);
  536. }
  537.  
  538.